package com.atguigu.dga.governance.assessor.quality;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.atguigu.dga.common.MetaConst;
import com.atguigu.dga.ds.bean.TDsTaskInstance;
import com.atguigu.dga.ds.service.TDsTaskInstanceService;
import com.atguigu.dga.governance.assessor.Assessor;
import com.atguigu.dga.governance.bean.AssessParam;
import com.atguigu.dga.governance.bean.GovernanceAssessDetail;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.apache.commons.lang3.time.DateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Component("PRODUCE_TIME_LINESS")
public class ProduceTimeLinessAssessor extends Assessor {

    // 1 当天的耗时
    // 2 前days天的 任务信息  由于 days 是变量 无法预估  临时查询数据库
    // 3  计算前days 的平均值
    // 4  求百分比
    // 5  实际百分比和参考百分比比较   打分

    @Autowired
    TDsTaskInstanceService tDsTaskInstanceService;

    @Override
    protected void assessProblem(GovernanceAssessDetail governanceAssessDetail, AssessParam assessParam) throws Exception {
        // 0 确保当天有任务
        if(assessParam.getTDsTaskInstanceList()==null ||assessParam.getTDsTaskInstanceList().size()==0){
            return;
        }

        // 1 当天的耗时
        List<TDsTaskInstance> dsTaskInstanceList = assessParam.getTDsTaskInstanceList();
        TDsTaskInstance tDsTaskInstanceSuccess=null;
        for (TDsTaskInstance tDsTaskInstance : dsTaskInstanceList) {
            if(   tDsTaskInstance.getState().toString().equals(MetaConst.TASK_STATE_SUCCESS.toString())){
                tDsTaskInstanceSuccess=tDsTaskInstance;
            }
        }
        // 取耗时
        long curDurationMs = tDsTaskInstanceSuccess.getEndTime().getTime() - tDsTaskInstanceSuccess.getStartTime().getTime();

        // 2 前days天的 任务信息  由于 days 是变量 无法预估  临时查询数据库
        String metricParamsJson = assessParam.getGovernanceMetric().getMetricParamsJson();
        JSONObject paramJsonObj = JSON.parseObject(metricParamsJson);
        Integer days = paramJsonObj.getInteger("days");
        BigDecimal paramPercent = paramJsonObj.getBigDecimal("percent");

        String assessDate = assessParam.getAssessDate();
        Date assessDateDt = DateUtils.parseDate(assessDate, "yyyy-MM-dd");
        List<String> beforeDateStrList=new ArrayList<>();
        for (int i = 1; i <=days; i++) {
            Date beforeDate = DateUtils.addDays(assessDateDt, 0 - i);
            String beforeDateStr = DateFormatUtils.format(beforeDate, "yyyy-MM-dd");
            beforeDateStrList.add(beforeDateStr);
        }

        String taskName = assessParam.getTableMetaInfo().getSchemaName() + "." + assessParam.getTableMetaInfo().getTableName();

        List<TDsTaskInstance> beforeTaskInstanceList = tDsTaskInstanceService.list(new QueryWrapper<TDsTaskInstance>()
                .in("date_format(start_time,'%Y-%m-%d')", beforeDateStrList)
                .eq("state", MetaConst.TASK_STATE_SUCCESS)
                .eq("name", taskName)
        );

        // 3  计算前days 的平均值
        Long  sumBeforeDurtionMs=0L;
        for (TDsTaskInstance beforeTaskInstance : beforeTaskInstanceList) {
            long beforeDurationMs = beforeTaskInstance.getEndTime().getTime() - beforeTaskInstance.getStartTime().getTime();
            sumBeforeDurtionMs+=beforeDurationMs;
        }
        Long avgBeforeDurtionMs= sumBeforeDurtionMs/beforeTaskInstanceList.size();

        // 4  求百分比
       // long curPercent = curDurationMs * 100L / avgBeforeDurtionMs;
        //
        BigDecimal curPercentBg = BigDecimal.valueOf(curDurationMs).
                movePointRight(2).
                divide(BigDecimal.valueOf(avgBeforeDurtionMs), 1, RoundingMode.HALF_UP);


        // 5  实际百分比和参考百分比比较   打分  compareTo  -1  0  1
        if(curPercentBg.compareTo(paramPercent)==1){
            //超过参考百分比
            governanceAssessDetail.setAssessScore(BigDecimal.ZERO);
            governanceAssessDetail.setAssessProblem("产出时效等于前"+days+"天平均值的"+curPercentBg+"%,超过参考百分比"+paramPercent+"%");
        }

    }
}
